package com.yc.service;
import com.yc.bean.Coupon;
import com.yc.mapper.CouponMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author zwei
 * @create 2024-09-05 15:11
 */
@Service
@Transactional
public class CouponService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private CouponMapper couponMapper;

    // 定时发布优惠券
    @Scheduled(cron = "0 0 0 * * ?") // 每天凌晨0点执行定时任务
    public void publishCoupon() {
        int discount = 10; // 优惠金额
        Coupon coupon = new Coupon();
        coupon.setCode("code001");
        coupon.setType("抵扣卷");
        coupon.setValue(String.valueOf(discount));
        coupon.setQuantity(5);  // 库存数量
        // 设置有效期为当天的开始和结束时间
        LocalDate today = LocalDate.now();
        LocalDateTime startDate = today.atStartOfDay();
        LocalDateTime endDate = today.atTime(23, 59, 59);
        // 格式化日期时间为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        coupon.setStart_date(startDate.format(formatter)); // 开始时间
        coupon.setEnd_date(endDate.format(formatter)); // 结束时间
        // 插入数据库
        couponMapper.insert(coupon);
        String cid = coupon.getCode();
        String couponKey = "coupon:stock:" + cid;
        String currentCouponKey = "coupon:current";
        // 存储优惠券库存数量到 Redis 并设置过期时间为当天结束时间
        redisTemplate.opsForValue().set(couponKey, 5);
        long secondsUntilEndOfDay = ChronoUnit.SECONDS.between(LocalDateTime.now(), endDate);
        redisTemplate.expire(couponKey, secondsUntilEndOfDay, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(currentCouponKey, cid, secondsUntilEndOfDay, TimeUnit.SECONDS);
    }

    //获取优惠卷
    public Coupon getCoupon(String uid) {
        //根据uid获取
        return (Coupon) redisTemplate.opsForValue().get(uid);
    }

    // 抢券操作
    public String grabCoupon(Integer uid) {
        String lockKey = "lock:coupon"; // 锁的键
        String lockValue = String.valueOf(System.nanoTime() + 1000 * 1000); // 锁的值，可以是当前时间纳秒数+超时时间
        String currentCouponKey = "coupon:current";
        try {
            // 尝试获取锁
            // 5秒超时时间
            Boolean acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 5, TimeUnit.SECONDS);
            if (Boolean.TRUE.equals(acquired)) {
                String cid = (String) redisTemplate.opsForValue().get(currentCouponKey);
                if (cid == null) {
                    return "未找到有效的优惠券";
                }
                String couponKey = "coupon:stock:" + cid;
                String userKey = "coupon:user:" + uid;
                Boolean alreadyGrabbed = redisTemplate.hasKey(userKey);
                if (Boolean.TRUE.equals(alreadyGrabbed)) {
                    return "您已经抢过优惠券";
                }
                Integer stock = (Integer) redisTemplate.opsForValue().get(couponKey);
                if (stock != null && stock > 0) {
                    Long newStock = redisTemplate.opsForValue().decrement(couponKey);
                    if (newStock >= 0) {
                        // 发放优惠券给用户
                        // 设置有效期为当天的开始和结束时间
                        LocalDateTime startDate = LocalDateTime.now();
                        LocalDateTime endDate =startDate.plusDays(1);
                        // 格式化日期时间为字符串
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        Coupon coupon = new Coupon();
                        coupon.setCode("code001");
                        coupon.setStart_date(startDate.format(formatter)); // 开始时间
                        coupon.setEnd_date(endDate.format(formatter)); // 结束时间
                        coupon.setType("优惠卷");
                        coupon.setValue("10");
                        coupon.setCid(1);
                        redisTemplate.opsForValue().set(String.valueOf(uid),coupon,1,TimeUnit.DAYS);
                        redisTemplate.opsForValue().set(userKey, true, 1, TimeUnit.DAYS);
                        return "抢券成功，您的优惠券已发放";
                    } else {
                        return "优惠券已抢完";
                    }
                } else {
                    return "优惠券已抢完";
                }
            } else {
                return "系统繁忙，请稍后再试";
            }
        } finally {
            // 释放锁
            String value = (String) redisTemplate.opsForValue().get(lockKey);
            if (lockValue.equals(value)) {
                redisTemplate.delete(lockKey);
            }
        }
    }
}
